#ifndef VENUS_ENV_MAP_EVN_MAP_DEMO_H
#define VENUS_ENV_MAP_EVN_MAP_DEMO_H

#include "common/venus.h"

#include <map>
#include <string>

#include "ui/glut_window.h"
#include "graphics/color.h"
#include "graphics/camera.h"
#include "graphics/fps_counter.h"

namespace venus {
class EnvMapDemo : public GlutWindow {
 public:
  EnvMapDemo();
  ~EnvMapDemo();
  bool Initialize(const char *model_file, const char *env_file);
 protected:
  void OnDisplay();
  void OnResize(int width, int height);
  void OnKeyboard(unsigned char key, int x, int y);
  void OnSpecialKey(int key, int x, int y);
  void OnMouse(int button, int state, int x, int y);
  void OnMouseMove(int x, int y);
  void OnIdle();
 private:
  typedef std::map<std::string, EffectCtrlGlut*> EffectCtrlMap;
 private:
  void ReleaseResources();
  void LoadEffects();
  void DestroyEffects();
  void DeleteRenderTargets();
  void InitRenderTargets();
  void RenderHdr();
  void RenderRgb();
  void RenderSkybox(const CubeTextureGL *env_map);
  void RenderModel(const CubeTextureGL *env_map);
  void RenderBloom();
 private:
  RenderDeviceFBO *device_;
  const Effect *effect_;
  //ReflectionEffect *reflection_effect_;
  //RefractionEffect *refraction_effect_;
  EffectCtrlGlut *effect_ctrl_;
  //ReflectionEffectCtrlGlut *reflection_effect_ctrl_;
  //RefractionEffectCtrlGlut *refraction_effect_ctrl_;
  EffectCtrlMap effect_ctrls_;
  OrbitPerspectiveCameraGL camera_;
  CubeTextureGL *cube_tex_;
  CubeTextureGL *hdr_cube_tex_;
  TriangleMesh *mesh_;
  Colorf color_;
  bool initialized_;

  ImageTextureGL *hdr_target_;
  ImageTextureGL *bloom_target_;
  static const int s_blur_passes = 3;
  ImageTextureGL *blur_x_target_[s_blur_passes];
  ImageTextureGL *blur_y_target_[s_blur_passes];
  ProgramGLSL *bloom_effect_;
  ProgramGLSL *blur_x_effect_;
  ProgramGLSL *blur_y_effect_;
  ProgramGLSL *tone_effect_;
  RenderBuffer *depth_buffer_;

  float bright_threshold_;
  float exposure_;
  float bloom_factor_;
  float ratio_;
  bool hdr_;

  static const int s_kRadius = 4;
  float s_gk[s_kRadius+1];
  Point last_pos_;
  bool left_button_down_;
  bool right_button_down_;
  FpsCounter fps_counter_;
};
} // namespace venus

#endif // VENUS_ENV_MAP_EVN_MAP_DEMO_H
